home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / pluginy Firefox / 3895 / 3895.xpi / chrome / compact-ce.jar / content / compact.js next >
Text File  |  2009-09-18  |  31KB  |  881 lines

  1. var CMCE = {
  2. // services
  3. firefox: document,
  4. prompts: Components.classes["@mozilla.org/embedcomp/prompt-service;1"].getService(Components.interfaces.nsIPromptService),
  5. util: null,
  6. pref: Components.classes["@mozilla.org/preferences-service;1"].
  7.     getService(Components.interfaces.nsIPrefService).getBranch("compact.menu."),
  8.  
  9. currentMenu: null,
  10. toolbar: null,
  11. menubar: null,
  12.  
  13. overlayFunction: function(oldFunc, oldCodeList, newCodeList) {
  14.     try {
  15.         var func = eval(oldFunc).toString();
  16.         for (var i = 0; i < oldCodeList.length; i++)
  17.             if (func.indexOf(oldCodeList[i]) < 0) return false;
  18.  
  19.         for (var i = 0; i < oldCodeList.length; i++) func = func.replace(oldCodeList[i], newCodeList[i]);
  20.         eval(oldFunc + "=" + func);
  21.  
  22.         return true;
  23.     } catch(e) { return false; }
  24. },
  25.  
  26. getItemListFromPref: function(pref) {
  27.     return this.fromStringtoArray(nsPreferences.copyUnicharPref("compact.menu." + pref), ",");
  28. },
  29.  
  30. fromStringtoArray: function(string, separator) {
  31.     var array = new Array();
  32.     var j = string.indexOf(separator);
  33.     for(var i=0; string; i++){
  34.         if (j == -1) {
  35.             array[i] = string;
  36.             break;
  37.         } else {
  38.             array[i] = string.substring(0, j);
  39.             string = string.substr( j+1 );
  40.             j = string.indexOf(separator);
  41.         }
  42.     }
  43.     return array;
  44. },
  45.  
  46. modifyGoMenu: function() {
  47.     var hide = this.pref.getBoolPref("compactGoMenu");
  48.     var menu = this.firefox.getElementById("goPopup");
  49.     var modify = false;
  50.     for (var item=menu.lastChild; item; item=item.previousSibling)
  51.         try{
  52.             if (modify) item.setAttribute("cm-visibility", (hide ? "hide" : ""));
  53.             else if (item.id == "endHistorySeparator") modify = true;
  54.         } catch(e) {}
  55.  
  56. // update history max count for FX3
  57.     var place = menu.getAttribute("place");
  58.     if (place) {
  59.         var m = place.match(/place:type=(\d+)&sort=(\d+)&maxResults=/g);
  60.         if (m) {
  61.             menu.setAttribute("place", m[0]+this.pref.getIntPref("maxCount"));
  62.             var gomenu = menu.parentNode;
  63.             gomenu.parentNode.insertBefore(gomenu, gomenu.nextSibling); // apply the change, this motion is  necessary
  64.         }
  65.     }
  66. },
  67.  
  68. hideItems: function() {
  69.     var ids = this.getItemListFromPref("hidelist");
  70.     var attr = "cm-visibility";
  71.     var menubar = this.firefox.getElementById("main-menubar");
  72.     for (var item=menubar.firstChild; item; item=item.nextSibling) {
  73.         if (item.tagName != "menu") continue;
  74.         var visible = true;
  75.         for (var j=0; j<ids.length; j++) if (item.id == ids[j]) {
  76.             visible = false;
  77.             break;
  78.         }
  79.         item.setAttribute(attr, (visible ? "show" : "hide"));
  80.     }
  81. },
  82.  
  83. hideMenuToolbar: function() {
  84.     setTimeout( function() {
  85.         var toolbar = CMCE.toolbar;
  86.  
  87.         if (toolbar.tempVisible && !window.shownPopup && !toolbar.mouseOver) {
  88.             for (var menu=CMCE.menubar.firstChild; menu; menu=menu.nextSibling)
  89.                 if (menu.getAttribute("_moz-menuactive")) return;
  90.             toolbar.tempVisible = false;
  91.         }
  92.     }, 0);
  93. },
  94.  
  95. showMenuToolbar: function() {
  96.     var toolbar = CMCE.toolbar;
  97.     if ((toolbar.collapsed || toolbar.getAttribute("moz-collapsed")) && !toolbar.getAttribute("tempVisible")) toolbar.tempVisible = true;
  98. },
  99.  
  100. setIDs: function(parent) {
  101.     for (var menu=parent.firstChild; menu; menu=menu.nextSibling)
  102.         try {
  103.             if (menu.tagName == "menu") this.setMenuItemsId(menu, parent);
  104.         } catch(e) {}
  105. },
  106.  
  107. setMenuItemsId: function(menu, parent) {
  108.     if (!menu.id) menu.id = parent.parentNode.id + "-" + escape(menu.getAttribute("label"));
  109.     if (!menu.firstChild) return;
  110.     for (var menuitem=menu.firstChild.firstChild; menuitem; menuitem=menuitem.nextSibling)
  111.         try {
  112.             if (
  113.                 menuitem.tagName == "menu" &&
  114.                 (this.isPureContainer(menuitem) || menuitem.id == "viewFullZoomMenu") &&
  115.                 this.isPureContainer(menuitem.firstChild)
  116.             )
  117.                 this.setMenuItemsId(menuitem, menu);
  118.             else {
  119.                 var label = menuitem.getAttribute("label");
  120.                 if (!menuitem.id && label) menuitem.id = menu.id + "-" + escape(label);
  121.             }
  122.         } catch(e) {}
  123. },
  124.  
  125. isPureContainer: function(item) {
  126.     if (
  127.         item &&
  128.         !item.getAttribute("onpopupshowing") &&
  129.         !item.getAttribute("onpopupshown") &&
  130.         !item.getAttribute("onpopuphiding") &&
  131.         !item.getAttribute("onpopuphidden") &&
  132.         !item.getAttribute("oncommand")
  133.     ) return true;
  134.     else return false;
  135. },
  136.  
  137. init: function() {
  138.     this.menubar = document.getElementById("main-menubar");
  139.     this.toolbar = document.getElementById("toolbar-menubar");
  140.  
  141.     var isLinux = navigator.platform.indexOf("Linux")  > -1;
  142.     var isFX3 = document.getElementById("placesCommands") ? true : false;
  143.  
  144.     try{ this.util = Components.classes["@mozilla.org/inspector/dom-utils;1"].getService(Components.interfaces["inIDOMUtils"]); }
  145.     catch(e){}
  146.  
  147. // add ids for menu items in menu bar before doing anything about the menus.
  148.     var menubar = this.menubar;
  149.     for (var item=menubar.firstChild; item; item=item.nextSibling) if (item.id == "tinymenu" || item.id == "mergedmenu") {
  150.         this.setIDs(item.firstChild);
  151.         break;
  152.     }
  153.     this.setIDs(menubar);
  154.  
  155. // check if first run or update
  156.     var currentVersion = "4.2.0";
  157.     var lastVersion = this.pref.getCharPref("lastVersion");
  158.     if (lastVersion != currentVersion) {
  159.         this.pref.setCharPref("lastVersion", currentVersion);
  160.  
  161.         // it is not first run if there is the old "firstrun" pref
  162.         try { var firstRun = this.pref.getBoolPref("firstrun") }
  163.         catch(e) { var firstRun = true }
  164.  
  165.         // first-run
  166.         if (!lastVersion && firstRun) {
  167.             // save the current hidden menu status as the setting of PM
  168.             // so hidden menus will not be shown after installing PM
  169.             var hiddenMenus = "";
  170.             for (var menu=this.menubar.firstChild; menu; menu=menu.nextSibling)
  171.                 if (menu.hidden && menu.tagName == "menu")
  172.                     hiddenMenus = hiddenMenus + (hiddenMenus == "" ? "" : ",") + menu.id;
  173.             nsPreferences.setUnicharPref( "compact.menu.hidelist", hiddenMenus);
  174.  
  175.             // alt toggle is not enabled as default as it still has bug in Linux
  176.             if (isLinux) this.pref.setBoolPref("altToggle", false);
  177.  
  178.             setTimeout( function(This) {
  179.                 This.prompts.alert(null, "Personal Menu", document.getElementById("compact-firstrun").label);
  180.                 // pop a confirm for asking whether add the buttons
  181.                 if (This.prompts.confirm(null, "Personal Menu", document.getElementById("compact-addbutton").label)) {
  182.                     var toolbar = document.getElementById("nav-bar");
  183.                     if (toolbar.collapsed) toolbar = This.toolbar;
  184.                     for (var i = 0; i < 3; i++)
  185.                         toolbar.insertItem(["compact-bk-menu2", "compact-go-menu2", "compact-menu-button"][i]);
  186.                     toolbar.setAttribute("currentset", toolbar.currentSet);
  187.                     document.persist(toolbar.id,"currentset");
  188.                     BrowserCustomizeToolbar();
  189.                 }
  190.             }, 750, this);
  191.         } else {
  192.             // clear old prefs
  193.             var prefs = [
  194.                 "advModeB", "advModeH", "error", "HMC", // since 3.0
  195.                 "defaultitemlist", "delay", "firstrun", "hidemenu", "hidemenubar", "oldStyle", // since 4.0
  196.                 "bookmarkMiddleClickOpens", "bookmarkRightClickOpens", // since 4.1pre
  197.                 "menuPosition-menu", "menuPosition-bookmarks", "menuPosition-history", // since 4.1
  198.                 "warning" // since 4.2.0
  199.             ];
  200.             for (var i=0; i<prefs.length; i++) try { this.pref.clearUserPref(prefs[i]) } catch(e) {}
  201.         }
  202.     }
  203.  
  204.     this.hideItems();
  205.     this.modifyGoMenu();
  206.  
  207.     // something causes "Bookmarks Toolbar" not working in FX 3.0
  208.     try {
  209.         initBookmarksToolbar();
  210.     } catch(e) {}
  211.     this.advMode();
  212.     this.updateIcon();
  213.  
  214. // modify functions
  215.     // modify for histroy max count
  216.     this.overlayFunction(
  217.         "updateGoMenu",
  218.         [
  219.             "if (count > 10",
  220.             "count = 10;"
  221.         ],
  222.         [
  223.             'var maxCount = CMCE.pref.getIntPref("maxCount"); if (count > maxCount',
  224.             "count = maxCount;"
  225.         ]
  226.     );
  227.  
  228.     setTimeout(function(This) {
  229.         // modify for bookmarks menu middle clicking for fx 2 or below
  230.         This.overlayFunction(
  231.             "BookmarksMenu.loadBookmarkMiddleClick",
  232.             [
  233.                 "BookmarksMenuDNDObserver.onDragCloseTarget",
  234.                 "BookmarksMenuDNDObserver.mCurrentDragOverTarget = null",
  235.                 "this.loadBookmark(aEvent, aEvent.target, aDS);"
  236.             ],
  237.             [
  238.                 'if (cmHideMenu) BookmarksMenuDNDObserver.onDragCloseTarget',
  239.                 'var cmHideMenu = CMCE.pref.getBoolPref("hidepopup"); if (cmHideMenu) BookmarksMenuDNDObserver.mCurrentDragOverTarget = null',
  240.                 'if (aEvent.target.localName != "menu" && !cmHideMenu && gBrowser.currentURI.spec == "about:blank" && !gBrowser.mIsBusy) CMCE.openUrl(aEvent); else this.loadBookmark(aEvent, aEvent.target, aDS);'
  241.             ]
  242.         );
  243.         // for fx 3
  244.         This.overlayFunction(
  245.             "BookmarksEventHandler.onClick",
  246.             [
  247.                 'if (target.localName == "menu"',
  248.                 "this.onCommand(aEvent);"
  249.             ],
  250.             [
  251.                 'var cmHideMenu = CMCE.pref.getBoolPref("hidepopup"); if (cmHideMenu) if (target.localName == "menu"',
  252.                 'if (aEvent.target.localName != "menu" && !cmHideMenu && gBrowser.currentURI.spec == "about:blank" && !gBrowser.mIsBusy) CMCE.openUrl(aEvent, true); else this.onCommand(aEvent);'
  253.             ]
  254.         );
  255.     }, 0, this);
  256.  
  257.     // modify for toggle menu toolbar
  258.     this.overlayFunction(
  259.         "onViewToolbarsPopupShowing",
  260.         [
  261.             'type != "menubar"',
  262.             'document.createElement("menuitem");'
  263.         ],
  264.         [
  265.             "true",
  266.             'document.createElement("menuitem"); if (toolbar.id == "toolbar-menubar") menuItem.addEventListener("command", function() { CMCE.toolbar._collapsed = !CMCE.toolbar._collapsed; if (CMCE.toolbar._collapsed) setTimeout(CMCE.prompts.alert, 0, null, "Personal Menu", document.getElementById("compact-warning").label); }, false); else{}'
  267.         ]
  268.     );
  269.  
  270.     // workaround with Menu Editor
  271.     this.overlayFunction(
  272.         "MenuEdit.editMenu",
  273.         ["if (!MenuEditRDF.getVisibility(node)"],
  274.         ['if (!MenuEditRDF.getVisibility(node) && p.id=="contentAreaContextMenu"']
  275.     );
  276.  
  277.     var toolbar = this.toolbar;
  278.  
  279. // handle menus toolbar toolgling
  280.     toolbar.setAttribute("hideBorderTop", this.pref.getBoolPref("hideBorderTop"));
  281.  
  282.     toolbar.__defineGetter__("_collapsed", function(){
  283.         return this.getAttribute("_collapsed") == "true";
  284.     });
  285.  
  286.     toolbar.__defineSetter__("_collapsed", function(){
  287.         this.setAttribute("_collapsed", arguments[0]);
  288.  
  289.         setTimeout(function(This, collapsed){
  290.             This.isToogling = true;
  291.             This.removeAttribute("collapsed");
  292.             document.persist(This.id, "collapsed");
  293.             This.collapsed = collapsed;
  294.             This.isToogling = false;
  295.         }, 0, this, arguments[0]);
  296.  
  297.         CMCE.pref.setBoolPref("toolbarCollapsed", arguments[0]);
  298.     });
  299.  
  300.     toolbar._collapsed = this.pref.getBoolPref("toolbarCollapsed");
  301.  
  302.     toolbar.addEventListener("DOMAttrModified", function(event){
  303.         if (event.attrName == "collapsed" && event.target == this) {
  304.             if (!this.isToogling && this.collapsed !=  this._collapsed) this.collapsed = this._collapsed;
  305.         }
  306.     }, true);
  307.  
  308. // add alt-toggle feature
  309.     toolbar.__defineGetter__("altToggle", function(){
  310.         return this.getAttribute("altToggle") == "true";
  311.     });
  312.  
  313.     toolbar.__defineSetter__("altToggle", function(){
  314.         this.setAttribute("altToggle", arguments[0]);
  315.     });
  316.  
  317.     toolbar.altToggle = this.pref.getBoolPref("altToggle");
  318.  
  319.     toolbar.__defineGetter__("tempVisible", function(){
  320.         return this.getAttribute("tempVisible") == "true";
  321.     });
  322.  
  323.     toolbar.__defineSetter__("tempVisible", function(){
  324.         this.setAttribute("tempVisible", arguments[0]);
  325.         if (!arguments[0])
  326.             setTimeout(function(This) {
  327.                 This.removeAttribute("tempVisible");
  328.             }, 250, this);
  329.     });
  330.  
  331.     setTimeout( function(toolbar) {
  332.         toolbar.addEventListener("DOMMenuBarInactive", function(event) {
  333.             if (this.altToggle) CMCE.hideMenuToolbar();
  334.         }, false);
  335.  
  336.          toolbar.addEventListener("DOMMenuBarActive", function(event){
  337.              if (this.altToggle) CMCE.showMenuToolbar();
  338.          }, false);
  339.  
  340.          toolbar.addEventListener("mouseover", function(){
  341.             this.mouseOver = true;
  342.          }, true);
  343.  
  344.          toolbar.addEventListener("mouseout", function(event){
  345.             this.mouseOver = false;
  346.             if (this.altToggle) CMCE.hideMenuToolbar();
  347.          }, true);
  348.     }, 100, toolbar);
  349.     if (isLinux) {
  350.           // in linux, menubar cannot be active after pressing alt key only, so we sould check the alt key pressing
  351.           window.addEventListener("keydown", function(event) {
  352.              this.altKey = event.keyCode == 18 && !event.ctrlKey && !event.shiftKey && !event.metaKey;
  353.           }, true);
  354.  
  355.           window.addEventListener("keyup", function(event) {
  356.              if (this.altKey && CMCE.toolbar.altToggle)
  357.                 if (CMCE.toolbar.tempVisible) CMCE.hideMenuToolbar();
  358.                 else setTimeout(CMCE.showMenuToolbar, 0);
  359.  
  360.              this.altKey = false;
  361.           }, true);
  362.  
  363.           // firefox cannot aware the release of alt key when main window is inactive
  364.           window.addEventListener("blur", function() {
  365.              this.altKey = false;
  366.           }, true);
  367.  
  368.           } else {
  369.         // prevent the PM buttons being active after pressing alt key only
  370.         window.addEventListener("keydown", function(event) {
  371.             if (event.keyCode == 18 && !event.ctrlKey && !event.shiftKey && !event.metaKey) {
  372.                 var cm_buttons = document.getElementsByAttribute("class", "cm-button");
  373.                 if (cm_buttons[0] && cm_buttons[0].getAttribute("classicMenu") == "true") return;
  374.                 for (var i=0; i<cm_buttons.length; i++) {
  375.                     cm_buttons[i].firstChild.firstChild.firstChild.hidePopup();
  376.                     cm_buttons[i].firstChild.hidden = true;
  377.                 }
  378.  
  379.                 setTimeout(function(cm_buttons) {
  380.                     for (var i=0; i<cm_buttons.length; i++) cm_buttons[i].firstChild.hidden = false;
  381.                 }, 0, cm_buttons);
  382.             }
  383.         }, true);
  384.     }
  385.  
  386.     window.addEventListener("popupshown", function(event) {
  387.         // event.target is main-window when tooltiptext shows
  388.         if (event.target.id != "main-window" && !this.shownPopup && event.target.tagName != "tooltip")
  389.             this.shownPopup = event.target;
  390.     }, true);
  391.  
  392.     window.addEventListener("popuphidden", function(event) {
  393.         if (event.target == this.shownPopup) {
  394.             this.shownPopup = null;
  395.             if (CMCE.toolbar.tempVisible) CMCE.hideMenuToolbar();
  396.  
  397.             // prevent showing menus toolbar after closeing menupopup by alt key
  398.             var toolbar = CMCE.toolbar;
  399.             if (toolbar.altToggle && !toolbar.tempVisible) toolbar.tempVisible = false;
  400.         }
  401.     }, true);
  402.  
  403. // add auto-switch menu feature
  404.     setTimeout( function(toolbar) {
  405.         toolbar.addEventListener("popupshowing", function(event) {
  406.             if (CMCE.pref.getBoolPref("popupmenu")) if(event.target.parentNode.parentNode.id == "main-menubar")
  407.                 CMCE.currentMenu = event.target;
  408.         }, true);
  409.  
  410.         toolbar.addEventListener("popuphidden", function(event) {
  411.             if(event.target.parentNode.parentNode.id == "main-menubar") CMCE.currentMenu = null;
  412.         }, true);
  413.  
  414.         toolbar.addEventListener("mouseover", function(event) {
  415.             var item = event.target;
  416.             var currentMenu = CMCE.currentMenu;
  417.             if (currentMenu && item.tagName == "menu" &&
  418.                     currentMenu.parentNode.parentNode.id != "main-menubar" &&
  419.                     item.parentNode.id == "main-menubar") {
  420.                 currentMenu.parentNode.removeAttribute("_moz-menuactive");
  421.                 currentMenu.hidePopup();
  422.                 item.setAttribute("_moz-menuactive", true);
  423.                 setTimeout(function(item){item.showPopup()}, 0, item.firstChild);
  424.             }
  425.         }, true);
  426.     }, 100, toolbar);
  427.  
  428. // add customized toolbar context menu feature
  429.     var context = document.getElementById("toolbar-context-menu");
  430.  
  431.     context.addEventListener("popupshowing", function(event) {
  432.         CMCE.onOpenMenu(this, event, this.cm_list);
  433.     }, true);
  434.  
  435.     context.addEventListener("popuphidden", function(event) {
  436.         CMCE.onCloseMenu(this, event);
  437.     }, true);
  438.  
  439.     context.cm_start = context.appendChild(document.createElement("menuseparator"));
  440.     context.cm_start.id = "cm-contextItem-start";
  441.     context.setAttribute("cmpopup", true);
  442.  
  443.     context.addEventListener("DOMMenuItemActive", CMCE.showSTXT, false);
  444.     context.addEventListener("DOMMenuItemInactive", CMCE.restoreSTXT, false);
  445. },
  446.  
  447. setAdv: function(target, type) {
  448.     var i = this.firefox.getElementsByAttribute("containerOf", type)[0];
  449.     if (!i) return;
  450.  
  451.     target.firstChild.original_position = target.firstChild.position;
  452.  
  453.     var point = this.firefox.createElement("separator");
  454.     point.id = "cmce-adv-restorePoint-"+target.id;
  455.     point.advRestorePoint = true;
  456.     point.hidden = true;
  457.     point.oriId = target.id;
  458.  
  459.     target.parentNode.replaceChild(point, target);
  460.     i.appendChild(target);
  461.     i.nextSibling.label = target.getAttribute("label");
  462.     target.isButton = true;
  463. },
  464.  
  465. advMode: function() {
  466.     // check if there is the menu
  467.     var target = this.firefox.getElementById(
  468.             ["bookmarksMenu", "yb_menu", "pof-menu", "ScrapBookMenu"][this.pref.getIntPref("BookmarksButton-menu")]);
  469.     // if not, use bookmarks menu
  470.     if (!target) target = this.firefox.getElementById("bookmarksMenu");
  471.     this.setAdv(target ? target : this.firefox.getElementById("bookmarks-menu"), "bookmarks");
  472.  
  473.     this.setAdv(this.firefox.getElementById("goPopup").parentNode, "history");
  474. },
  475.  
  476. stopPropagation: function(event) {
  477.     event.stopPropagation();
  478. },
  479.  
  480. closeAllPopup: function(item) {
  481.     var menu = item.parentNode;
  482.     while (menu.parentNode.parentNode.tagName == "menupopup" || menu.parentNode.parentNode.tagName == "popup")
  483.         menu = menu.parentNode.parentNode;
  484.     menu.hidePopup();
  485. },
  486.  
  487. middleClickHandler: function(event) {
  488.     if (event.button == 1) {
  489.         //a special fix for undo closed tab menu
  490.         if (event.currentTarget.id == "historyUndoMenu")
  491.             HistoryMenu.populateUndoSubmenu();
  492.  
  493.         setTimeout( function(menu) {
  494.             if (menu.getAttribute("open") == menu.getAttribute("disabled")) CMCE.closeAllPopup(menu);
  495.         }, 0, event.currentTarget);
  496.     }
  497. },
  498.  
  499. updateMenuList: function() {
  500.     for (var i = 0; i < 2; i++) {
  501.         var pop = this.firefox.getElementById(["menubutton-popup", "toolbar-context-menu"][i]);
  502.         if (pop) pop.cm_list = nsPreferences.copyUnicharPref("compact.menu." + ["itemlist", "showlist"][i]);
  503.  
  504.         //this.initializeMenu(pop, this.fromStringtoArray(pop.cm_list, ","));
  505.     }
  506. },
  507.  
  508. onOpenMenu: function(menu, event, list) {
  509.     if (event.target != menu) return;
  510.     if (!menu.cm_initialized) {
  511.         if (document.getElementById("cmd_CustomizeToolbars").getAttribute("disabled")) return;
  512.         this.initializeMenu(menu, this.fromStringtoArray(list, ","));
  513.     }
  514.     this.createMenu(menu, true, menu.id);
  515. },
  516.  
  517. initializeMenu: function(menu, itemsId) {
  518.     var topMenu = menu;
  519.     var initializingToolbar = false;
  520.     var toolbarPalette = document.getElementById("navigator-toolbox").palette;
  521.     var editMenuItem = document.getElementById(
  522.         menu.id == "toolbar-context-menu" ? "compact-showhide-prefs" : "compact-extra-prefs");
  523.  
  524.     for (var i = 0; i < itemsId.length; i++) {
  525.         if (itemsId[i] == "----")
  526.             menu.insertBefore(document.createElement((menu.tagName=="toolbar" ? "toolbar" : "menu") + "separator"), menu.cm_end);
  527.         else if (itemsId[i] == "cm-submenu") {
  528.             menu = menu.insertBefore(document.getElementById(itemsId[i]).cloneNode(true), menu.cm_end);
  529.             menu.setAttribute("label", itemsId[++i]);
  530.             if (itemsId[++i] != "empty") menu.setAttribute("accesskey", itemsId[i]);
  531.             menu = menu.firstChild;
  532.         }
  533.         else if (itemsId[i] == "cm-submenu-end" || itemsId[i] == "cm-buttons-box-end") {
  534.             if (!menu.hasChildNodes()) menu.appendChild(editMenuItem.cloneNode(true));
  535.             menu = menu.parentNode.parentNode;
  536.             initializingToolbar = false;
  537.         }
  538.         else if (itemsId[i] == "cm-toolbar-spring")
  539.             menu.appendChild(document.createElement("toolbarspring")).setAttribute("flex", 1);
  540.         else if (itemsId[i] == "cm-toolbar-spacer")
  541.             menu.appendChild(document.createElement("toolbarspacer"));
  542.         else if (initializingToolbar) {
  543. //            var item = document.getElementById(itemsId[i]);
  544. //            if (item && item.parentNode.localName == "toolbar") continue;
  545.             for (var item = toolbarPalette.firstChild; item && item.id != itemsId[i]; item = item.nextSibling);
  546.             if (item) {
  547.                 menu.appendChild(item.cloneNode(true));
  548.                 switch(item.id) {
  549.                     case "ietab-button":
  550.                         IeTab.prototype.updateToolButton();
  551.                         break;
  552.                 }
  553.             }
  554.         }
  555.         else if (itemsId[i] == "cm-buttons-box") {
  556.             menu = menu.insertBefore(document.getElementById(itemsId[i]).cloneNode(true), menu.cm_end).firstChild;
  557.             menu.cm_menu_position = topMenu.position;
  558.             for (var j=0; j<3; j++) menu.setAttribute(["adv", "iconsize", "mode"][j], itemsId[++i]);
  559.             initializingToolbar = true;
  560.         }
  561.         else {
  562.             var item = document.getElementById(itemsId[i]);
  563.             if (!item) continue;
  564.  
  565.             var dummy = item.cloneNode(false);
  566.             dummy.disabled = true;
  567.             dummy.id = "cmRestorePoint-" + itemsId[i];
  568.             dummy.target = item;
  569.              // these menuitems need to be updated their status when their original menu shows
  570.             var identity = item.command ? item.command : item.id;
  571.             var update_cmd;
  572.              switch (identity) {
  573.                  case "historyUndoMenu":
  574.                      update_cmd = "HistoryMenu.populateUndoSubmenu();";
  575.                      break;
  576.                  case "historyUndoWindowMenu":
  577.                      update_cmd = "HistoryMenu.populateUndoWindowSubmenu();";
  578.                      break;
  579.                 case "Browser:SaveFrame":
  580.                     update_cmd = "getContentAreaFrameCount();";
  581.                     break;
  582.                 case "cmd_fullZoomToggle":
  583.                     update_cmd = "FullZoom.updateMenu();";
  584.                     break;
  585.                 case "checkForUpdates":
  586.                     update_cmd = "buildHelpMenu();";
  587.                     break;
  588.                 case "ietab-toolsmenu":
  589.                     update_cmd = "IeTab.prototype.updateToolsMenuItem({originalTarget: document.getElementById('menu_ToolsPopup')});";
  590.                     break;
  591.                 case "cmd_undo": case "cmd_redo": case "cmd_cut": case "cmd_copy": case "cmd_paste":
  592.                 case "cmd_selectAll": case "cmd_delete": case "cmd_switchTextDirection":
  593.                     update_cmd = "goUpdateCommand('" + identity + "');";
  594.                     break;
  595.                 default:
  596.                     update_cmd = "";
  597.             }
  598.             dummy.update_cmd = update_cmd;
  599.  
  600.             menu.insertBefore(dummy, menu.cm_end);
  601.             item.cm_restorePoint = dummy;
  602.         }
  603.     }
  604.  
  605.     if (!menu.hasChildNodes()) menu.appendChild(editMenuItem.cloneNode(true));
  606.     menu.cm_initialized = true;
  607. },
  608.  
  609. createMenu: function(menu, isTopMenu, topMenuId) {
  610.     for (var i = 0; i < menu.childNodes.length; i++) {
  611.         var item = menu.childNodes[i];
  612.          if (item.id == "cm-submenu") {
  613.              this.createMenu(item.firstChild, false, topMenuId);
  614.              continue;
  615.          }
  616.  
  617.          var target = item.target
  618.          if (!target) continue;
  619.  
  620.          if (item.update_cmd)
  621.              try {
  622.                 eval(item.update_cmd);
  623.             } catch(e) {}
  624.  
  625.         var itemPosition = item.nextSibling;
  626.         target.parentNode.replaceChild(item, target);
  627.         menu.insertBefore(target, itemPosition);
  628.  
  629.         if (isTopMenu) {
  630.             target.addEventListener("popupshowing", CMCE.stopPropagation, false);
  631.             target.addEventListener("popuphidden", CMCE.stopPropagation, false);
  632.             if (target.tagName == "menu") target.addEventListener("click", CMCE.middleClickHandler, false);
  633.         }
  634.     }
  635. },
  636.  
  637. onCloseMenu: function(menu, event) {
  638.     if (event.target != menu) return;
  639.     setTimeout(this.restoreMenu, 0, menu, true);
  640. },
  641.  
  642. restoreMenu: function(menu, isTopMenu) {
  643.     var restore = !menu.cm_start;
  644.     for (var i = 0; i < menu.childNodes.length; i++) {
  645.         var item = menu.childNodes[i];
  646.         if (item == menu.cm_end) break;
  647.  
  648.         if (restore) CMCE.restoreItem(item, menu, isTopMenu);
  649.         else if (menu.cm_start == item) restore = true;
  650.     }
  651. },
  652.  
  653. restoreItem:function(item, menu, inTopMenu) {
  654.     if (item.id == "cm-submenu") CMCE.restoreMenu(item.firstChild, false);
  655.     else if (item.cm_restorePoint) {
  656.         var position = item.nextSibling;
  657.         item.cm_restorePoint.parentNode.replaceChild(item, item.cm_restorePoint);
  658.         menu.insertBefore(item.cm_restorePoint, position);
  659.  
  660.         if (inTopMenu) {
  661.             item.removeEventListener("popupshowing", CMCE.stopPropagation, false);
  662.             item.removeEventListener("popuphidden", CMCE.stopPropagation, false);
  663.             item.removeEventListener("click", CMCE.middleClickHandler, false);
  664.         }
  665.     }
  666. },
  667.  
  668. bkclick: function(button, event) {
  669.     if (event.target != button || event.button == 0) return;
  670.     try { switch(this.pref.getIntPref("bookmarks" + (event.button == 1 ? "Middle" : "Right") + "ClickOpens")) {
  671.         case 1:
  672.             try {
  673.                 PlacesCommandHook.bookmarkCurrentPage(true, PlacesUtils.bookmarksMenuFolderId);
  674.             } catch(e) {
  675.                 addBookmarkAs(document.getElementById("content"), false);
  676.             }
  677.             break;
  678.         case 2: toggleSidebar("viewBookmarksSidebar"); break;
  679.         case 3: toOpenWindowByType("bookmarks:manager","chrome://browser/content/bookmarks/bookmarksManager.xul"); break;
  680.         case 4:
  681.             try {
  682.                 gBookmarkAllTabsHandler.doCommand();
  683.             } catch(e) {
  684.                 addBookmarkAs(document.getElementById("content"), true);
  685.             }
  686.             break;
  687.         case 5: toggleSidebar("viewYBookmarksSidebar"); break;
  688.         case 6: yAddBookMark.open(); break;
  689.         case 7: gPofUI.openAddToFavoritesDialog(); break;
  690.         case 8: gPofUI.openOrganizeFavoritesDialog(); break;
  691.         case 9: sbBrowserOverlay.execCapture(0, null, false, "urn:scrapbook:root"); break;
  692.         case 10: sbBrowserOverlay.execCapture(0, null, true , "urn:scrapbook:root"); break;
  693.         case 11: sbMenuHandler.execCaptureAllTabs(); break;
  694.         case 12: toggleSidebar("viewScrapBookSidebar"); break;
  695.         case 13: sbCommonUtils.openManageWindow(); break;
  696.         case 14: PlacesCommandHook.showPlacesOrganizer("AllBookmarks"); break;
  697.         case 15: sbBrowserOverlay.execBookmark('ScrapBookContextPicking');
  698.     }} catch(e) {
  699.         // show toolbar context when it gets an error.
  700. //        // when we right-click the content and the context showed,
  701. //        // toolbar context doesn't show in a correct position, so we don't use this fixing yet
  702. //            if (event.button==2)
  703. //                document.getElementById("toolbar-context-menu").showPopup(event.currentTarget, event.clientX+2, event.clientY+2, "context");
  704.     }
  705. },
  706. goclick: function(button, event) {
  707.     if (event.target != button || event.button == 0) return;
  708.     try { switch(this.pref.getIntPref("history" + (event.button == 1 ? "Middle" : "Right") + "ClickOpens")) {
  709.         case 1: toggleSidebar("viewHistorySidebar"); break;
  710.         case 2:
  711.             try {
  712.                 gBrowser.undoRemoveTab();
  713.             } catch(e) {
  714.                 undoCloseTab();
  715.             }
  716.             break;
  717.         case 3: openMe("window"); break;
  718.         case 5: openMe("sidebar"); break;
  719.         case 6: PlacesCommandHook.showPlacesOrganizer("History");
  720.     }} catch(e) {
  721.     }
  722. },
  723.  
  724. menuclick: function(button, event) {
  725.     if (event.target == button && this.pref.getIntPref("menuMiddleClickOpens") > 0 && event.button == 1)
  726.         window.openDialog(
  727.             "chrome://compact-ce/content/compactPrefDialog.xul",
  728.             "Personal Menu",
  729.             "chrome,centerscreen,dependent,minimizable,resizable",
  730.             "menubutton-tree");
  731. },
  732.  
  733. showAll: function() {
  734.     this.toolbar._collapsed = false;
  735.     this.toolbar.tempVisible = false;
  736.  
  737.     nsPreferences.setUnicharPref( "compact.menu.hidelist", "");
  738.     this.hideItems();
  739. },
  740.  
  741. openUrl: function(event, isFX3BK) {
  742.     openUILinkIn(
  743.         isFX3BK ? event.originalTarget.node.uri : event.target.statusText,
  744.         gBrowser.currentURI.spec == "about:blank" && !gBrowser.mIsBusy ? "current" : "tab"
  745.     );
  746. },
  747.  
  748. buttonPopShowHide: function(pop, event) {
  749.     if (event.target != pop) return;
  750.     var showing = event.type == "popupshowing";
  751.     if (this.pref.getBoolPref("popupmenu")) this.currentMenu = showing ? pop : null;
  752.     pop.parentNode.parentNode.nextSibling.setAttribute("open", showing); // in fx3beta , "button.open" method doesn't work
  753. },
  754.  
  755. mouseover: function(el, event) {
  756.     var menu = el.firstChild;
  757.  
  758. // setPseudo
  759.     this.pseudoHandle(el, event, true);
  760.  
  761. // popup menu
  762.     if (this.currentMenu && this.currentMenu != menu.firstChild) {
  763.         this.currentMenu.parentNode.removeAttribute("_moz-menuactive");
  764.         this.currentMenu.hidePopup();
  765.         setTimeout(function(M){
  766.             M.firstChild.showPopup();
  767.             M.setAttribute("_moz-menuactive", true);
  768.         }, 0, menu);
  769.     }
  770.  
  771. // update tooltip
  772.     if (event.target == menu && el.parentNode.getAttribute("classicMenu") != "true") {
  773.         menu.tooltipText = el.getAttribute("Tip");
  774.         if (this.pref.getBoolPref("enableHotkey")) {
  775.             var accesskey = menu.getAttribute("accesskey");
  776.             if (accesskey) menu.tooltipText += " (Alt+" + accesskey.toUpperCase() + ")";
  777.         }
  778.     }
  779. },
  780.  
  781. addButtonEventListener: function(menubar, type) {
  782.     var menu = menubar.firstChild;
  783.  
  784.     if (menu && !menu.eventAdded) {
  785.         if (type == "go") menu.addEventListener("click", function(event) {
  786.             if(this.isButton) CMCE.goclick(this, event);
  787.         }, false);
  788.         else menu.addEventListener("click", function(event) {
  789.             if(this.isButton) CMCE.bkclick(this, event);
  790.         }, false);
  791.         menu.firstChild.addEventListener("popupshowing", function(event) {
  792.             if(this.parentNode.isButton) CMCE.buttonPopShowHide(this, event);
  793.         }, false);
  794.         menu.firstChild.addEventListener("popuphidden", function(event) {
  795.             if(this.parentNode.isButton) CMCE.buttonPopShowHide(this, event);
  796.         }, false);
  797.         menu.eventAdded = true;
  798.     }
  799. },
  800.  
  801. showSTXT:function(event) {
  802.     var url = event.target.statusText;
  803.     if (url) {
  804.         var status = document.getElementById("statusbar-display");
  805.         CMCE.menubar._originalStatusText = status.label;
  806.         status.label = url;
  807.     }
  808. },
  809.  
  810. restoreSTXT: function(event) {
  811.     if (event.target.statusText)
  812.         document.getElementById("statusbar-display").label = CMCE.menubar._originalStatusText;
  813. },
  814.  
  815. updateIcon: function() {
  816. // set the appearance of buttons
  817.     var notFX1_5 = this.firefox.getElementById("Tools:Addons");
  818.     var isFX3 = this.firefox.getElementById("placesCommands");
  819.  
  820.     var positions = ["before_end", "after_end", "before_start", "after_start"];
  821.     var enable_hotkey = this.pref.getBoolPref("enableHotkey");
  822.     var noarrow = this.pref.getBoolPref("noarrow");
  823.     var classic_menu = !this.pref.getBoolPref("buttonStyle");
  824.  
  825.     var buttons = this.firefox.getElementsByAttribute("class", "cm-button");
  826.     for (var i=0; i<buttons.length; i++) {
  827.         var button = buttons[i].lastChild;
  828.         var type = buttons[i].firstChild.getAttribute("containerOf");
  829.  
  830.         button.setAttribute("noarrow", noarrow);
  831.  
  832.         var menu = button.previousSibling.firstChild;
  833.         menu.firstChild.position = positions[this.pref.getIntPref("position-" + type)];
  834.         if (!enable_hotkey) {
  835.             menu.original_accessKey = menu.getAttribute("accesskey");
  836.             menu.removeAttribute("accesskey");
  837.         } else if (menu.original_accessKey)
  838.             menu.setAttribute("accesskey", menu.original_accessKey);
  839.  
  840.         button.parentNode.setAttribute("classicMenu", classic_menu);
  841.         if (!classic_menu) menu.setAttribute("flex", 1);
  842.         else menu.removeAttribute("flex");
  843.         menu.parentNode.appendChild(menu); // update the flex status
  844.         button.hidden = classic_menu;
  845.  
  846.         if (notFX1_5) button.setAttribute("cmFirefox2", true);
  847.         if (noarrow || !notFX1_5) button.setAttribute("orient", "vertical");
  848.         else button.setAttribute("orient", "horizontal");
  849.  
  850.         // in FX3, this attribute makes the statustexts of bookmark and history items cannot be shown
  851.         if (!isFX3) button.previousSibling.setAttribute("statusbar", "statusbar-display");
  852.         button.parentNode.appendChild(button); // update the orient and mousethrough status
  853.  
  854.         if (type != "menu") {
  855.             button.parentNode.setAttribute("context",
  856.                 this.pref.getIntPref(type+"RightClickOpens") > 0 ? "" : "toolbar-context-menu");
  857.         } else button.previousSibling.hidden = false;
  858.     }
  859.  
  860.     this.updateMenuList();
  861. },
  862.  
  863. pseudoHandle: function(el, event, hover) {
  864.     el = el.nextSibling;
  865.     if (el.hidden) return;
  866.     this.setPseudo(el, event, hover);
  867. },
  868.  
  869. setPseudo: function(el, event, hover) {
  870.     try {
  871.         if (event.button != 0) return;
  872.  
  873.         this.util.setContentState(el, 4);
  874.         //since onmousedown is fired before onpopupshown, which is the moment that "open" is set, so need some delay
  875.         setTimeout( function(util, el, hover) {
  876.             if(el.getAttribute("open") == "true") util.setContentState((hover ? el.ownerDocument.documentElement : el), 1);
  877.         }, 1, this.util, el, hover);
  878.     } catch(e) {}
  879. }
  880.  
  881. }